const DIGITS: &str = "0123456789ABCDEF";

pub fn convert_base(num_str: &str, to_base: u32) -> String {
    let Some((num, base)) = num_str.split_once('(') else {
        panic!("invalid input format: {}", num_str);
    };

    let base: u8 = base.trim_end_matches(')').parse().expect("invalid base");

    let mut decimal = 0u64;
    for c in num.to_uppercase().chars() {
        if let Some(pos) = DIGITS.chars().position(|x| x == c) {
            if pos >= base as usize {
                panic!("Invalid digit '{}' for base {}", c, base);
            }

            decimal = decimal.checked_mul(base as u64).expect("Overflow occurred");
            decimal = decimal.checked_add(pos as u64).expect("Overflow occurred");
        } else {
            panic!("Invalid character '{}' in input", c);
        }
    }

    if decimal == 0 {
        return "0".to_string();
    }

    let mut digits_str = String::new();
    while decimal > 0 {
        digits_str.push(
            DIGITS
                .chars()
                .nth((decimal % to_base as u64) as usize)
                .unwrap(),
        );
        decimal /= to_base as u64;
    }

    digits_str.chars().rev().collect::<String>().to_lowercase()
}
